package com.aws.service.impl;

import com.amazonaws.AmazonClientException;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;
import com.aws.service.AwsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * @description:
 * @author: libugu@cskaoyan.com
 * @date 2024/1/27 - 9:32
 */
@Service
@Slf4j
public class AwsServiceImpl implements AwsService {

    @Resource
    AmazonS3 amazonS3;

    @Override
    public void singleUpload(MultipartFile file) {
        try {
            // 获取文件名和输入流
            String fileName = file.getOriginalFilename();
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentType("application/xml");
            metadata.setContentEncoding("UTF-8");
            metadata.setContentLength(file.getSize());
            PutObjectRequest request = new PutObjectRequest("mylibugu", "/0127/" + fileName, file.getInputStream(), metadata);
            // 执行上传操作
            amazonS3.putObject(request);
            System.out.println("文件上传成功！");
        } catch (IOException e) {
            System.out.println("文件上传失败：" + e.getMessage());
        }
    }

    @Override
    public void segmentUpload(MultipartFile uploadFile) {

        String key = uploadFile.getOriginalFilename();
        String bucketName = "mylibugu";
        key = "/segment/" + key;

        InitiateMultipartUploadRequest initiateRequest = new InitiateMultipartUploadRequest(bucketName, key);
        InitiateMultipartUploadResult initResult = amazonS3.initiateMultipartUpload(initiateRequest);
        String uploadId = initResult.getUploadId();

        try {
            long partSize = 5 * 1024 * 1024; // 设置每个分段的大小为5MB

            File file = convertMultipartFileToFile(uploadFile); // 将MultipartFile转换为File
            long fileLength = file.length();

            int totalParts = (int) Math.ceil((double) fileLength / partSize);

            List<PartETag> partETags = new ArrayList<>();

            try (InputStream inputStream = new FileInputStream(file)) { // 使用try-with-resources语句自动关闭输入流
                for (int partNumber = 1; partNumber <= totalParts; partNumber++) {
                    long start = (partNumber - 1) * partSize;
                    long end = Math.min(start + partSize, fileLength);
                    long size = end - start;

                    inputStream.skip(start);

                    UploadPartRequest uploadRequest = new UploadPartRequest()
                            .withBucketName(bucketName)
                            .withKey(key)
                            .withUploadId(uploadId)
                            .withPartNumber(partNumber)
                            .withInputStream(inputStream)
                            .withPartSize(size);

                    UploadPartResult uploadResult = amazonS3.uploadPart(uploadRequest);
                    partETags.add(uploadResult.getPartETag());
                }
            }

            CompleteMultipartUploadRequest completeRequest = new CompleteMultipartUploadRequest(bucketName, key, uploadId, partETags);
            amazonS3.completeMultipartUpload(completeRequest);

            log.info("分段上传完成");
        } catch (Exception e) {
            log.error("分段上传失败:{}", e.getMessage());
            // 清理已经成功的部分，保持一致性
            AbortMultipartUploadRequest abortRequest = new AbortMultipartUploadRequest(bucketName, key, uploadId);
            amazonS3.abortMultipartUpload(abortRequest);
        }
    }

    @Override
    public void singleDownload(String downloadPath, HttpServletResponse response) {


        S3Object fullObject = amazonS3.getObject(new GetObjectRequest("mylibugu", downloadPath));
        String contentType = fullObject.getObjectMetadata().getContentType();
        System.out.println("contentType==============" + contentType);

        String[] pathParts = downloadPath.split("/");
        String fileName = pathParts[pathParts.length - 1]; // 获取文件名
        try {
            fileName = URLEncoder.encode(fileName, "UTF-8"); // 对文件名进行URL编码
            fileName = fileName.replace("+", "%20"); // 替换空格
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        response.setContentType(contentType);
        response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");

        try (InputStream inputStream = fullObject.getObjectContent();
             OutputStream outputStream = response.getOutputStream()) {
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            System.out.println("下载完成 99999999999999");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void getAllFiles() {
        ListObjectsV2Request req = new ListObjectsV2Request().withBucketName("mylibugu").withMaxKeys(2);
        ListObjectsV2Result result;

        do {
            result = amazonS3.listObjectsV2(req);
            for (S3ObjectSummary objectSummary : result.getObjectSummaries()) {
                log.info("- {} (size: {})", objectSummary.getKey(), objectSummary.getSize());
            }
            String nextContinuationToken = result.getNextContinuationToken();
            req.setContinuationToken(nextContinuationToken);
        } while (result.isTruncated());
    }

    @Override
    public void deleteSingleFile(String deletePath) {

        try {
            amazonS3.deleteObject(new DeleteObjectRequest("mylibugu", deletePath));
            log.info("File deleted successfully.");
        } catch (AmazonClientException e) {
            e.printStackTrace();
            log.error("File deleted unsuccessfully.cause:{}",e.getMessage());
        }
    }


//    private void displayTextInputStream(S3ObjectInputStream objectContent,File downloadFile) throws IOException {
//        try (OutputStream outputStream = new FileOutputStream(downloadFile)) {
//            byte[] buffer = new byte[4096];
//            int bytesRead;
//            while ((bytesRead = objectContent.read(buffer)) != -1) {
//                outputStream.write(buffer, 0, bytesRead);
//            }
//            System.out.println("下载完成 99999999999999");
//        }
//    }

    private File convertMultipartFileToFile(MultipartFile multipartFile) throws IOException {
        File file = new File(multipartFile.getOriginalFilename());
        try (OutputStream os = new FileOutputStream(file)) {
            os.write(multipartFile.getBytes());
        }
        return file;
    }
}
